%{
#include <stdlib.h>
#include "ast.h"
#include "lrparser.tab.h"

//char* yytext;
void yyerror(char *);
//判断是否符合16进制
int Digit(char ch)
{
	if (ch >= '0' && ch <= '9')
		return ch-48;
	else if (ch >= 'A' && ch <= 'F')
	{
		return ch-55;
	}
	else if (ch >= 'a' && ch <= 'f')
	{
		return ch-87;
	}
	else
		return -1;
}

//解析数字
int ParseInputInteger(char *InputWordFromOut, int dex)
{
	int i = 0;
	for(i=0;;i++)	//	计算字符串长度
	{
		if(InputWordFromOut[i] == '\0')
		{
			break;
		}
	}
	int SUM = 0;
	int Weights = 1;
	int n;
	if (dex == 10)
	{
		n = -1;
	}
	else if (dex == 8)
	{
		n = 0;
	}
	else
	{
		n = 1;
	}

	for (i--; i != n ; i--)
	{
		SUM = SUM + Weights * Digit(InputWordFromOut[i]);
		Weights = Weights * dex;
	}
	return SUM;	
}


%}

ID 		[_a-zA-Z][_a-zA-Z0-9]*
INT_DEX [1-9][0-9]*|[0]
INT_HEX [0][Xx]([1-9][0-9a-fA-F]*|[0])
INT_OCT [0][0-7]*

%%
"/*"([^\*]|(\*)+[^/])*"*/"				{ /* ignore commentline */ }
"//".*				{ /* ignore commentline */ }
int					{ yylval.Token = tok_INT; return Y_INT;}
const				{ yylval.Token = tok_CONST; return Y_CONST;}
void				{ yylval.Token = tok_VOID; return Y_VOID;}
if					{ yylval.Token = tok_IF; return Y_IF;}
else				{ yylval.Token = tok_ELSE; return Y_ELSE;}
while				{ yylval.Token = tok_WHILE; return Y_WHILE;}
break				{ yylval.Token = tok_BREAK; return Y_BREAK;}
continue			{ yylval.Token = tok_CONTINUE; return Y_CONTINUE;}
return				{ yylval.Token = tok_RETURN; return Y_RETURN;}

","					{ yylval.Token = tok_COMMA; return Y_COMMA;}
";"					{ yylval.Token = tok_SEMICOLON; return Y_SEMICOLON;}
"["					{ yylval.Token = tok_LSQUARE; return Y_LSQUARE;}
"]"					{ yylval.Token = tok_RSQUARE; return Y_RSQUARE;}
"{"					{ yylval.Token = tok_LBRACKET; return Y_LBRACKET;}
"}"					{ yylval.Token = tok_RBRACKET; return Y_RBRACKET;}
"("					{ yylval.Token = tok_LPAR; return Y_LPAR;}
")"					{ yylval.Token = tok_RPAR; return Y_RPAR;}

"+"					{ yylval.Token = tok_ADD; return Y_ADD;}
"-"					{ yylval.Token = tok_SUB; return Y_SUB;}
"!"					{ yylval.Token = tok_NOT; return Y_NOT;}
"*"					{ yylval.Token = tok_MUL; return Y_MUL;}
"/"					{ yylval.Token = tok_DIV; return Y_DIV;}
"%"					{ yylval.Token = tok_MODULO; return Y_MODULO;}
"<"					{ yylval.Token = tok_LESS; return Y_LESS;}
">"					{ yylval.Token = tok_GREAT; return Y_GREAT;}
"<="				{ yylval.Token = tok_LESSEQ; return Y_LESSEQ;}
">="				{ yylval.Token = tok_GREATEQ; return Y_GREATEQ;}
"=="				{ yylval.Token = tok_EQ; return Y_EQ;}
"!="				{ yylval.Token = tok_NOTEQ; return Y_NOTEQ;}
"&&"				{ yylval.Token = tok_AND; return Y_AND;}
"||"				{ yylval.Token = tok_OR; return Y_OR;}
"="					{ yylval.Token = tok_ASSIGN; return Y_ASSIGN;}
\n					{ /* ignore enter */ }
[ \t]				{ /* ignore whitespace */ }
{INT_DEX} 			{ yylval.Value = atoi(yytext); return NUMBER;}
{INT_HEX} 			{ yylval.Value = ParseInputInteger(yytext, 16); return NUMBER;}
{INT_OCT} 			{ yylval.Value = ParseInputInteger(yytext, 8); return NUMBER;}
{ID}				{ yylval.Stiring = strdup(yytext); return IDentifier;}
. 					{ yyerror("invalid character");}
%%

int yywrap(void)
{
	return 1;
}
